/*
 * Copyright 2002-2016 the Beijing Brain Technology co.,LTD http://www.bris.cn/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bris.niosocket.mapping;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.support.ApplicationObjectSupport;

import com.bris.niosocket.message.IMessage;

/**
 * 增加拦截器的逻辑</br> 
 * 2016年2月17日</br>
 * 
 * @author xunaidong
 * @since 1.0.0
 */
public abstract class AbstractHandlerMapping extends ApplicationObjectSupport
		implements HandlerMapping {

	private Object defaultHandler;// 默认处理请求的handler

	private final List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>();// 业务请求拦截器链
	
	/**
	 * @return the defaultHandler
	 */
	public Object getDefaultHandler() {
		return defaultHandler;
	}

	/**
	 * @param defaultHandler
	 *            the defaultHandler to set
	 */
	public void setDefaultHandler(Object defaultHandler) {
		this.defaultHandler = defaultHandler;
	}

	/**
	 * Initializes the interceptors.
	 */
	@Override
	protected void initApplicationContext() throws BeansException {
		detecInterceptors();//感知拦截器
	}

	/**
	 * 
	 * 感知注册的拦截器 <br/>
	 * 
	 * @author xunaidong
	 * @since 1.0.0
	 */
	protected void detecInterceptors() {
		interceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(
				getApplicationContext(), HandlerInterceptor.class, true, false)
				.values());
	}

	/**
	 * 由当前的请求查询其对应的处理链,若未查询到则返回默认的处理器</br>
	 * 
	 * @param request
	 *            current socket request
	 * @return the corresponding handler instance, or the default handler
	 * @see #getHandlerInternal
	 */
	public final HandlerChain getHandler(IMessage request) throws Exception {
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = getApplicationContext().getBean(handlerName);
		}
		return getHandlerChain(handler, request);
	}

	/**
	 * 
	 * 返回拦截器集合<br/>
	 * 
	 * @author xunaidong
	 * @return
	 * @since 1.0.0
	 */
	protected final HandlerInterceptor[] getInterceptors() {
		int count = this.interceptors.size();
		return (count > 0 ? this.interceptors
				.toArray(new HandlerInterceptor[count]) : null);
	}

	/**
	 * 
	 * 从当前请求中查询处理器,若未查询到则返回null <br/>
	 * 
	 * @author xunaidong
	 * @param request
	 * @return
	 * @throws Exception
	 * @since 1.0.0
	 */
	protected abstract Object getHandlerInternal(IMessage request)
			throws Exception;

	/**
	 * 
	 * 根据请求返回一个处理链 <br/>
	 * 
	 * @author xunaidong
	 * @param handler
	 * @param request
	 * @return
	 * @since 1.0.0
	 */
	protected HandlerChain getHandlerChain(Object handler, IMessage request) {
		HandlerChain chain = (handler instanceof HandlerChain ? (HandlerChain) handler
				: new HandlerChain(handler));
		chain.addInterceptors(getInterceptors());
		return chain;
	}
}
